package com.example.myproject.jackson;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.core.io.NumberInput;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;

import java.io.IOException;

/**
 * Created by xi on 2018/9/21.
 * BeanDeserializer
 * 参考NumberDeserializers 这个实现类
 */
public class JacksonLongDeSerializer extends NewPrimitiveOrWrapperDeserializer<Long> {
    private static final long serialVersionUID = 1L;
    public JacksonLongDeSerializer(){this(Long.TYPE, null);};
    public JacksonLongDeSerializer(Class<Long> cls, Long nvl) {
        super(cls, nvl, 0L);
    }

    // since 2.6, slightly faster lookups for this very common type
    @Override
    public boolean isCachable() { return true; }

    @Override
    public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        if (p.hasToken(JsonToken.VALUE_NUMBER_INT)) {
            return p.getLongValue();
        }
        return _parseLong(p, ctxt);
    }

    protected final Long _parseLong(JsonParser p, DeserializationContext ctxt) throws IOException
    {
        switch (p.getCurrentTokenId()) {
            // NOTE: caller assumed to usually check VALUE_NUMBER_INT in fast path
            case JsonTokenId.ID_NUMBER_INT:
                return p.getLongValue();
            case JsonTokenId.ID_NUMBER_FLOAT:
                if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_FLOAT_AS_INT)) {
                    _failDoubleToIntCoercion(p, ctxt, "Long");
                }
                return p.getValueAsLong();
            case JsonTokenId.ID_STRING:
                String text = p.getText().trim();
                //解决Long的特殊值问题
                if (text.length() == 0) {
                    //return (Long) _coerceEmptyString(ctxt, _primitive);
                    return UpdateSpecialConstant.LONG_SPECAIL_VALUE;
                }

                if (_hasTextualNull(text)) {
                    return (Long) _coerceTextualNull(ctxt, _primitive);
                }
                _verifyStringForScalarCoercion(ctxt, text);
                // let's allow Strings to be converted too
                try {
                    return Long.valueOf(NumberInput.parseLong(text));
                } catch (IllegalArgumentException iae) { }
                return (Long) ctxt.handleWeirdStringValue(_valueClass, text,
                        "not a valid Long value");
            // fall-through
            case JsonTokenId.ID_NULL:
                return (Long) _coerceNullToken(ctxt, _primitive);
            case JsonTokenId.ID_START_ARRAY:
                return _deserializeFromArray(p, ctxt);
        }
        // Otherwise, no can do:
        return (Long) ctxt.handleUnexpectedToken(_valueClass, p);
    }
}
